package org.projectwithoutname.ui.pages;


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import model.Serie;
import model.SeriesPackSerie;
import model.Workspace;
import model.diagram.part.ModelDiagramEditorUtil;
import model.provider.ModelItemProviderAdapterFactory;

import org.eclipse.core.internal.resources.ProjectDescription;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.handlers.IHandlerService;
import org.projectwithoutname.commons.Commons;
import org.projectwithoutname.commons.ICommandIds;
import org.projectwithoutname.emf.EMFLoader;
import org.projectwithoutname.ui.menus.PopUpMenu;
import org.projectwithoutname.ui.view.SuperView;



@SuppressWarnings("restriction")
public class MainPage extends SuperView{
	public static String ID = ICommandIds.MAIN_PAGE;
	private Composite layout;
	private ArrayList<Button> icons = new ArrayList<Button>();
	private ArrayList<String> iconsName = new ArrayList<String>();
	private static final int WIDTH = Commons.SELECTION_WIDTH;
	private static final int HEIGHT = Commons.SELECTION_HEIGHT;
	
	private AdapterFactoryEditingDomain editingDomain;
	private ComposedAdapterFactory adapterFactory;
	private String domainModelFilePath = "Workspace/Workspace.package";
	
	private Serie selection = null;
	
	private void initWorkspace() {
		try {
			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
			IProject project = workspaceRoot.getProject("Workspace");
			
			if(!project.exists())
				project.create(null);
			if(!project.isOpen())
				project.open(null);
			
			IProjectDescription description = new ProjectDescription();
			description.setName("Workspace");
			description.setComment("Workspace");
			project.setDescription(description, null);
			
			String diagramModelFilePath = "Workspace/Workspace.diagram";
			final URI diagramModelFileURI = URI.createPlatformResourceURI(diagramModelFilePath, false);
			final URI ModelFileURI = URI.createPlatformResourceURI(domainModelFilePath, false);
			
			Resource diagram = ModelDiagramEditorUtil.createDiagram(diagramModelFileURI, ModelFileURI, new NullProgressMonitor());
			
			root = (Workspace) EMFLoader.loadDomain(domainModelFilePath);
			root.eResource().save(Collections.EMPTY_MAP);
			System.out.println("Resrouce: "+root.eResource());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void initView(){
		try{
			IWorkspace workspaceResource = ResourcesPlugin.getWorkspace();
			System.out.println("\nRefresh: ");
			
			for(IProject project : workspaceResource.getRoot().getProjects()){
				if (project.isOpen()){
					if (project.getDescription().getComment().equals("Workspace")){
						Workspace workspace = (Workspace) getResource("Workspace/Workspace.package").getContents().get(0);
						root = workspace;
					}
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	public void refresh(){
		if (root.getGroupOfSeries() != null){
			for (SeriesPackSerie serieLink : root.getGroupOfSeries().getAggregatedSerie()){
				String name = serieLink.getSerie().getName();
				ImageData imageData = new ImageData(serieLink.getSerie().getImages().get(0).getPath());
				Image image = new Image(getLayout().getDisplay(), imageData);
				CreateButton(name, image);
			}
		}
	}

	private void setSelection(Serie serie){
		selection = serie;
	}
	
	public Serie getSelection(){
		return selection;
	}
	
	protected void initializeEditingDomain() {
		// Create an adapter factory that yields item providers.
		//
		adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);

		adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
		adapterFactory.addAdapterFactory(new ModelItemProviderAdapterFactory());
		adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());

		// Create the command stack that will notify this editor as commands are executed.
		//
		BasicCommandStack commandStack = new BasicCommandStack();

		editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack, new HashMap<Resource, Boolean>());
	}
	
	@Override
	public void createPartControl(Composite parent) {
		Device device = parent.getDisplay();
		initializeEditingDomain();
		Color color = new Color(device, 122, 153, 194);
		parent.setBackground(color);
		
		parent.setLayout(null);
		setLayout(parent); 
		
		getLayout().addControlListener(new ControlListener() {
			
			@Override
			public void controlResized(ControlEvent e) {
				organizedButtons();
			}
			
			@Override
			public void controlMoved(ControlEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
		
		try {
			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
			IProject project = workspaceRoot.getProject("Workspace");
			
			if(!project.exists())
				initWorkspace();
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		initView();
		refresh();
	}
	
	private void setMenu(Control control){
		PopUpMenu popUpMenu = new PopUpMenu(control);
		MenuItem newItem  = popUpMenu.createMenuIntem("New", SWT.CASCADE);
		popUpMenu.separator();
		
		MenuItem performItem = popUpMenu.createMenuIntem("Perform aditional information", SWT.CASCADE);
		
		popUpMenu.separator();
		popUpMenu.createMenuIntem("Close", SWT.NONE);
		popUpMenu.createMenuIntem("Delete", SWT.CASCADE);
		
		popUpMenu.createSubMenu(newItem);
		popUpMenu.createMenuIntem(newItem.getMenu(), "Season", SWT.NONE).addSelectionListener(new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
		
		popUpMenu.createMenuIntem(newItem.getMenu(), "Episode", SWT.NONE).addSelectionListener(new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
				try {
					handlerService.executeCommand(ICommandIds.NEW_EPISODE, null);
				} catch (Exception ex) {
					ex.printStackTrace();
					throw new RuntimeException(ICommandIds.NEW_EPISODE + " not found");
				}
			}
			
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
		
		popUpMenu.createSubMenu(performItem);
		popUpMenu.createMenuIntem(performItem.getMenu(), "Actor", SWT.NONE);
		popUpMenu.createMenuIntem(performItem.getMenu(), "Character", SWT.NONE);
		popUpMenu.createMenuIntem(performItem.getMenu(), "Image", SWT.NONE);
		
		
		popUpMenu.createMenu(control);
		
	}
	private void setLayout(Composite layout){
		this.layout = layout;
	}
	
	private Composite getLayout(){
		return layout;
	}
	
	private void organizedButtons(){
		int i = 0, x = 10, y = 10;
		int lineSize =(getLayout().getSize().x / (WIDTH + 20)) < 1? 1:getLayout().getSize().x / (WIDTH + 20);
		
		for (Button button : icons){
			if (i<lineSize){
				button.setBounds(x, y, WIDTH, HEIGHT);
				x += WIDTH + 20;
				i++;
			}
			else{
				i=1;
				x = 10;
				y += HEIGHT + 20;
				button.setBounds(x, y, WIDTH, HEIGHT);
				x += WIDTH + 20;
			}
		}
	}
	
	public void CreateButton(final String name, Image image){
		boolean flag = false;
		if (icons.isEmpty()){
			final Button button = new Button(getLayout(), SWT.NONE);
			setMenu(button);
			iconsName.add(name);
			if (image != null)
				button.setImage(image);
			button.addListener(SWT.Selection, new Listener() {
				@Override
				public void handleEvent(Event event) {
					for(SeriesPackSerie seriePack : root.getGroupOfSeries().getAggregatedSerie()){
						Serie serie = seriePack.getSerie();
						System.out.println(name);
						System.out.println(serie);
						if (serie.getName().equals(name)){
							setSelection(serie);
							System.out.println(getSelection());
							break;
						}
					}
					hookDoubleClickCommand(button, name);
				}
			});
			icons.add(button);
			organizedButtons();
		}
		else{	
			for(String obj : iconsName){
				if (obj.equals(name)){flag = true; break;}
			}
			if (!flag){
				final Button button = new Button(getLayout(), SWT.NONE);
				setMenu(button);
				iconsName.add(name);
				if (image != null)
					button.setImage(image);
				button.addListener(SWT.Selection, new Listener() {
					@Override
					public void handleEvent(Event event) {
						for(SeriesPackSerie seriePack : root.getGroupOfSeries().getAggregatedSerie()){
							Serie serie = seriePack.getSerie();
							if (serie.getName().equals(name)){
								setSelection(serie);
								break;
							}
							
						}
						hookDoubleClickCommand(button, name);
					}
				});
				icons.add(button);
				organizedButtons();
			}
		}
	}
	
	private void hookDoubleClickCommand(final Button button, final String name) {
		button.setFocus();
		button.addMouseListener(new MouseListener() {
			
			@Override
			public void mouseUp(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseDown(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
				try {
					handlerService.executeCommand(ICommandIds.CMD_OPEN_EDITOR, null);
				} catch (Exception ex) {
					ex.printStackTrace();
					throw new RuntimeException(ICommandIds.CMD_OPEN_EDITOR + " not found");
				}
				
			}
		});
	}
	
	@Override
	public void setFocus() {
	}

}
